
#include "RouletteWheel.h"

//Inicializa un casillero de la ruleta
RouletteSlot::RouletteSlot(unsigned int id, double potential){
	RouletteSlot::id = id;
	RouletteSlot::potential = potential;
}

//Retorna el potencial de la casilla
double RouletteSlot::getPotential() const {
	return RouletteSlot::potential;
}

//Retorna el Id asociado a la casilla
unsigned int RouletteSlot::getId(){
	return RouletteSlot::id;
}

//Agrega una nueva casilla
void RouletteWheelSelection::addSlot(unsigned int id, double potential){
	RouletteSlot tmp(id, potential);
	slots.push_back(tmp);
	readyForSpin = false;
}

//Remueve una casilla
void RouletteWheelSelection::removeSlot(unsigned int id){
	unsigned int x;
	bool found = false;
	for(x = 0; x < slots.size(); x++)
		if (slots[x].getId() == id){
			found = true;
			break;
		}
	
	if (found) {
		slots.erase(slots.begin() + x);
		readyForSpin = false;
	}
}

//Prepara la ruleta para la seleccion
void RouletteWheelSelection::prepareRouletteWheel(){
	unsigned int x;
	double totalPotential = 0.0;

	RouletteWheelSelection::sortSlots();
	for(x = 0; x < slots.size(); x++)
		totalPotential += slots[x].getPotential();

	slots[0].probability = slots[0].getPotential()/totalPotential;
	for(x = 1; x < slots.size(); x++)
		slots[x].probability = slots[x-1].probability + slots[x].getPotential()/totalPotential;
	
	readyForSpin = true;
}

//Ordena las casillas de menor a mayor
void RouletteWheelSelection::sortSlots(){
	sort(slots.begin(), slots.end(), SortByChance());
}

//Limpia la ruleta, eliminando todas las casillas
void RouletteWheelSelection::clear(){
	slots.clear();
	readyForSpin = false;
}

//Selecciona un numero dentro de las casillas existentes
unsigned int RouletteWheelSelection::spin(){
	double chance = rand()/(RAND_MAX+1.0);
	unsigned int x;

	if(!readyForSpin) prepareRouletteWheel();
	
	if ((chance >= 0) && (chance <= slots[0].probability))
		return slots[0].getId();
	for(x = 0; x < slots.size();  x++){
		if (x == slots.size()-1) return slots[x].getId();
		if ((chance > slots[x].probability) && (chance <= slots[x+1].probability))
			return slots[x+1].getId();
	}

	return slots[0].getId();
}